// Copyright 2018 Adrien Guinet <adrien@guinet.me>
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dffi_impl.h"
#include <llvm/Support/Path.h>
#include <llvm/Support/VirtualFileSystem.h>

using namespace clang;
using namespace llvm;

// Implemented in clang_res.h included below
static void initVFS(vfs::InMemoryFileSystem&);

// Used by initVFS!
static void addPath(vfs::InMemoryFileSystem& VFS, const char* Path, const uint8_t* Data, size_t Len)
{
  assert(sys::path::is_relative(Path) && "path must be relative!");
  SmallString<1024> FullPath;
  (StringRef{dffi::details::getClangResRootDirectory()} + "/" + Path).toStringRef(FullPath);
  VFS.addFile(FullPath, time(NULL), 
    MemoryBuffer::getMemBuffer(StringRef{(const char*)Data, Len}, "", false));
}

static IntrusiveRefCntPtr<vfs::FileSystem> createClangResFileSystem()
{
  auto* VFS = new vfs::InMemoryFileSystem{};
  initVFS(*VFS);
  return IntrusiveRefCntPtr<vfs::FileSystem>{VFS};
}

// Data generated by cmake!
#include <dffi/clang_res.h>

// "Public" API
IntrusiveRefCntPtr<vfs::FileSystem> dffi::details::getClangResFileSystem()
{
  static IntrusiveRefCntPtr<vfs::FileSystem> FS = createClangResFileSystem();
  return FS;
}

const char* dffi::details::getClangResRootDirectory()
{
  return "/__clang_resources";
}
